package com.fansl.allround.auth.provider.sys.openid;

import com.fansl.allround.common.core.constant.enums.OauthTypeEnum;
import com.fansl.allround.common.security.provider.AbstractUserDetailsAuthenticationProvider;
import com.fansl.allround.common.security.service.AllroundUserDetailsService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

/**
 * @author fansl
 * @Description: 系统用户第三方登录校验逻辑
 * @date 2019/9/26 13:23
 */
@Slf4j
@AllArgsConstructor
public class SysUserOpenIdAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider {

    private AllroundUserDetailsService userDetailsService;

    /**
     * 自定义认证校验
     *
     * @param userDetails
     * @param authentication
     * @throws AuthenticationException
     */
    @Override
    protected void additionalAuthenticationChecks(UserDetails userDetails, Authentication authentication) throws AuthenticationException {

    }

    /**
     * 查找用户信息
     *
     * @param openid
     * @param authentication
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected UserDetails retrieveUser(String openid, Authentication authentication) throws AuthenticationException {
        SysUserOpenIdAuthenticationToken token = (SysUserOpenIdAuthenticationToken) authentication;
        String openId = (String) token.getPrincipal();
        String providerId = token.getProviderId();
        OauthTypeEnum oauthType = OauthTypeEnum.getByCode(Integer.parseInt(providerId));
        UserDetails user = userDetailsService.loadUserByOauthType(openId, oauthType);
        if (user == null) {
            log.warn("用户未找到，openId:{},providerId:{}", openId, providerId);
            throw new UsernameNotFoundException("用户不存在");
        }
        return user;
    }

    /**
     * 生成认证信息
     *
     * @param authentication
     * @param user
     * @return
     */
    @Override
    protected Authentication createSuccessAuthentication(Authentication authentication, UserDetails user) {
        SysUserOpenIdAuthenticationToken token = (SysUserOpenIdAuthenticationToken) authentication;
        SysUserOpenIdAuthenticationToken authenticationToken =
                new SysUserOpenIdAuthenticationToken(user, token.getProviderId(),
                        token.getAccessToken(), user.getAuthorities());
        authenticationToken.setDetails(authenticationToken.getDetails());
        return authenticationToken;
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return SysUserOpenIdAuthenticationToken.class.isAssignableFrom(authentication);
    }
}
